/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.huawei.healthecology.client;

import com.huawei.healthecology.data.platform.PlatformRequest;
import com.huawei.healthecology.data.platform.PlatformResponse;
import com.huawei.healthecology.json.JsonMapperType;
import com.huawei.healthecology.module.ClientModule;
import com.huawei.healthecology.operator.H5RemoteOperator;
import com.huawei.healthecology.operator.PlatformOperationCode;

import lombok.Builder;
import ohos.agp.components.webengine.WebView;

import java.util.Optional;

/**
 * The Web view operation client
 */
public class H5Client {
    private static final String TAG = "H5Client";

    private static final int GENERAL_FAILED_OPERATION_CODE = 1_0001;

    private static final String CLIENT_NOT_INJECTED = "Error";

    private final WebView webViewInstance;

    /**
     * The builder constructor for H5Client
     *
     * @param webView The web view instance
     * @param mapperType The custom json mapper type
     */
    @Builder
    public H5Client(WebView webView, JsonMapperType mapperType) {
        webViewInstance = webView;
        Optional.ofNullable(mapperType).ifPresent(ClientModule::configJsonMapper);
    }

    /**
     * To process the H5/web view request
     *
     * @param remoteMethod The method name for Java replying the reponse
     * @param platformRequest The platform request
     * @return A response string in Json format
     */
    public String onProcessRequest(String remoteMethod, String platformRequest) {
        Optional<PlatformRequest> parsedRequest = ClientModule.getParser()
            .flatMap(parser -> parser.mapTo(platformRequest, PlatformRequest.class));
        H5RemoteOperator remoteOperator = H5RemoteOperator.builder()
            .webViewInstance(webViewInstance)
            .remoteJsMethod(remoteMethod)
            .build();
        PlatformResponse response = parsedRequest
            .flatMap(request -> PlatformOperationCode.processH5Operation(remoteOperator, request))
            .orElse(PlatformResponse.builder()
                .resultCode(GENERAL_FAILED_OPERATION_CODE)
                .build());
        return Optional.of(response)
            .flatMap(result -> ClientModule.getParser().flatMap(parser -> parser.stringify(result)))
            .orElse(CLIENT_NOT_INJECTED);
    }
}
